package com.library.common.base

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import com.library.common.R
import com.library.common.dto.MessageEvent
import com.library.common.ext.clickNoRepeat
import com.library.common.ext.dismissLoadingExt
import com.library.common.ext.getVmClazz
import com.library.common.ext.showLoadingExt
import com.library.common.toast.XToast
import com.yanzhenjie.permission.AndPermission
import com.yanzhenjie.permission.runtime.Permission
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.ParameterizedType

/**
 * 作者：SimGa
 * 日期：2019-11-27
 * 时间：14:10
 */
abstract class BaseFragment<VM : BaseViewModel, DB : ViewDataBinding> : Fragment() {
    lateinit var viewModel: VM
    lateinit var mContext: BaseActivity<*, *>
    lateinit var mBinding: DB

    //是否第一次加载
    private var isFirst: Boolean = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mContext = activity as BaseActivity<*, *>
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val cls =
            (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<*>
        if (ViewDataBinding::class.java != cls && ViewDataBinding::class.java.isAssignableFrom(cls)) {
            mBinding = DataBindingUtil.inflate(inflater, layoutId, container, false)
            mBinding.lifecycleOwner = this
            return mBinding.root
        }
        return inflater.inflate(layoutId, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewModel = createViewModel()
        initView(savedInstanceState)
        initLoadingUiChange()
        observeData()
        eventHandling()
    }

    abstract val layoutId: Int
    abstract fun initView(savedInstanceState: Bundle?)
    open fun eventHandling() {}
    open fun lazyLoadData() {}
    open fun observeData() {}
    open fun handleEvent(msg: MessageModel) {}

    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onEvent(event: MessageEvent) {
    }

    override fun onResume() {
        super.onResume()
        onVisible()
    }

    /**
     * 是否需要懒加载
     */
    private fun onVisible() {
        if (lifecycle.currentState == Lifecycle.State.STARTED && isFirst) {
            view?.post {
                lazyLoadData()
                isFirst = false
            }
        }
    }

    /**
     * 注册 UI 事件
     */
    private fun initLoadingUiChange() {
        viewModel.defUI.run {
            loading.observeInFragment(this@BaseFragment) {
                if (it.isShow) {
                    showLoadingExt(it.loadingMessage)
                } else {
                    dismissLoadingExt()
                }
            }
            msgEvent.observeInFragment(this@BaseFragment) {
                handleEvent(it)
            }
        }
    }

    /**
     * 创建viewModel
     */
    private fun createViewModel(): VM {
        return ViewModelProvider(this).get(getVmClazz(this))
    }

    protected fun finish() {
        mContext.finish()
    }

    fun finishResult(intent: Intent) {
        mContext.finishResult(intent)
    }

    fun startActivity(bundle: Bundle, target: Class<*>) {
        mContext.startActivity(bundle, target)
    }

    /**
     * 多个点击事件，都是同一个效果时，使用该方法
     */
    protected fun onClick(onClick: (view: View) -> Unit, vararg views: View) {
        views.forEach {
            it.clickNoRepeat(500) { view ->
                onClick.invoke(view)
            }
        }
    }

    fun startForResult(bundle: Bundle?, requestCode: Int, target: Class<*>) {
        val intent = Intent(mContext, target)
        if (bundle != null) {
            intent.putExtras(bundle)
        }
        startActivityForResult(intent, requestCode)
        mContext.overridePendingTransition(R.anim.slide_left_in, R.anim.slide_left_out)
    }

    override fun onDestroy() {
        super.onDestroy()
        //通知系统进行一次回收
        EventBus.getDefault().unregister(this)
        System.gc()
    }

    protected fun pressiom(phone: String) {
        AndPermission.with(this)
            .runtime()
            .permission(
                Permission.READ_PHONE_STATE,
                Permission.CALL_PHONE
            )
            .onDenied {
                if (AndPermission.hasAlwaysDeniedPermission(this, it)) {
                    // 这些权限被用户总是拒绝。
                    XToast.normal("需要必要权限以正常使用功能")
                }
            }
            .onGranted {
                callPhone(phone)
            }.start()
    }

    /**
     * 拨打电话（跳转到拨号界面，用户手动点击拨打）
     *
     * @param phoneNum 电话号码
     */
    private fun callPhone(phoneNum: String) {
        val intent = Intent(Intent.ACTION_DIAL)
        val data = Uri.parse("tel:$phoneNum")
        intent.data = data
        startActivity(intent)
    }
}
